package com.dandelion.common.utils;

import com.rockit.core.pojo.JsonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SafeJsonResult {
    private static final Logger logger = LoggerFactory.getLogger(SafeJsonResult.class);

    public static <T> JsonResult exec(Invocation0<T> invocation) {
        try {
            T t = invocation.invoke();
            return JsonResult.ok(t);
        } catch (IllegalArgumentException ex) {
            logger.error("PARAM_ERROR|" + ex.getMessage());
            return JsonResult.error(1, ex.getMessage());
        } catch (Exception e) {
            logger.error("", e);
            return JsonResult.error(1, "error");
        }
    }

    public static <T, P1> JsonResult exec(Invocation1<T, P1> invocation, P1 p1) {
        return exec(() -> invocation.invoke(p1));
    }

    public static <T, P1, P2> JsonResult exec(Invocation2<T, P1, P2> invocation, P1 p1, P2 p2) {
        return exec(() -> invocation.invoke(p1, p2));
    }

    public static <T, P1, P2, P3> JsonResult exec(Invocation3<T, P1, P2, P3> invocation, P1 p1, P2 p2, P3 p3) {
        return exec(() -> invocation.invoke(p1, p2, p3));
    }

    public static JsonResult exec(VoidInvocation0 invocation) {
        try {
            invocation.invoke();
            return JsonResult.ok();
        } catch (Exception e) {
            logger.error("", e);
            return JsonResult.error(1, "error");
        }
    }

    public static <P1> JsonResult exec(VoidInvocation1<P1> invocation, P1 p1) {
        return exec(() -> invocation.invoke(p1));
    }

    public static <P1, P2> JsonResult exec(VoidInvocation2<P1, P2> invocation, P1 p1, P2 p2) {
        return exec(() -> invocation.invoke(p1, p2));
    }

    public static <P1, P2, P3> JsonResult exec(VoidInvocation3<P1, P2, P3> invocation, P1 p1, P2 p2, P3 p3) {
        return exec(() -> invocation.invoke(p1, p2, p3));
    }

    @FunctionalInterface
    public static interface Invocation0<T> {
        T invoke();
    }

    @FunctionalInterface
    public static interface Invocation1<T, P1> {
        T invoke(P1 p1);
    }

    @FunctionalInterface
    public static interface Invocation2<T, P1, P2> {
        T invoke(P1 p1, P2 p2);
    }

    @FunctionalInterface
    public static interface Invocation3<T, P1, P2, P3> {
        T invoke(P1 p1, P2 p2, P3 p3);
    }

    @FunctionalInterface
    public static interface VoidInvocation0 {
        void invoke();
    }

    @FunctionalInterface
    public static interface VoidInvocation1<P1> {
        void invoke(P1 p1);
    }

    @FunctionalInterface
    public static interface VoidInvocation2<P1, P2> {
        void invoke(P1 p1, P2 p2);
    }

    @FunctionalInterface
    public static interface VoidInvocation3<P1, P2, P3> {
        void invoke(P1 p1, P2 p2, P3 p3);
    }
}
